<template>
	<el-row class="row-items" :gutter="20">
		<!-- tag列表组 -->
		<el-tag
			:type="tagType"
			closable
			:size="size"
			v-for="(item, key) in items"
			:key="config.key ? item[config.key] : index"
			disable-transitions
			@close="handleDelete(item)"
		>{{item[config.label]}}</el-tag>

		<!-- 添加支持的子房型选择器 -->
		<div class="box-add" v-show="isAdding">
			<!-- 下拉选择框新增 -->

			<!-- 注意：为了传值给父组件，添加组件需要用v-show来显示/隐藏。通过刷新key值的方式来更新 -->
			<el-select
				v-model="selectedItem"
				placeholder="请选择"
				filterable
				:key="selectKey"
				:size="size"
				:value-key="config.key || 'value'"
				automatic-dropdown
				ref="newTagSelectRef"
				@change="selectionChangeHandler"
				@blur="selectBlurHandler"
				v-if="type === 'select'"
			>
				<el-option
					v-for="(item, index) in validOptions"
					:key="config.key ? item[config.key] : index"
					:label="config.label ? item[config.label] : item"
					:value="config.value ? item[config.value] : item"
				></el-option>
			</el-select>

			<!-- input输入框新增 -->
			<el-input
				class="el-input-tag-new"
				:size="size"
				ref="newTagInputRef"
				v-model="inputValue"
				@blur="inputBlurHandler"
				v-if="type === 'text'"
			/>
		</div>

		<!-- 点击显示选择器的按钮 -->
		<el-button
			type="primary"
			plain
			icon="el-icon-circle-plus-outline"
			@click="showAddComponent"
			:size="size"
			v-show="!isAdding && (type !== 'select' || selectable)"
		>添加</el-button>
	</el-row>
</template>

<script>
	import _ from "lodash";

	export default {
		name: "cc-tag-group",

		props: {
			// 标识添加模式，支持选择器或文本输入框
			type: {
				type: String,
				default: "text",
				validator: function(value) {
					return ["select", "text"].includes(value);
				}
			},
			// 标识控件大小，支持large/medium/small/mini
			size: {
				type: String,
				default: "mini",
				validator: function(value) {
					return ["large", "medium", "small", "mini"].includes(value);
				}
			},
			// 标识tag类型，支持el-tag所有原生类型
			tagType: {
				type: String,
				default: "success"
			},
			// 已添加的记录列表
			items: {
				type: Array,
				default: () => []
			},
			// select模式下可供选择的选项列表
			selections: {
				type: Array,
				default: () => []
			},
			// select模式下el-select控件的具体配置
			config: {
				type: Object,
				default: () => ({
					key: "",
					label: ""
				})
			}
		},

		data() {
			return {
				// 是否处于添加状态，决定添加组件是否显示
				isAdding: false,
				// 文本框添加模式的绑定值
				inputValue: "",
				// 选择器添加模式的绑定值
				selectedItem: null,
				// 选择器的唯一key值，向父组件传值后更改为随机值
				selectKey: "defaultKey"
			};
		},

		computed: {
			// 标识选择器模式是否还可以继续添加
			selectable: function() {
				return this.validOptions.length > 0;
			},

			// 选择器添加模式下可用来添加的备选项
			validOptions: function() {
				return _.difference(this.selections, this.items);
			}
		},

		methods: {
			// 添加按钮的点击事件
			showAddComponent() {
				this.isAdding = true;
				this.$nextTick(() => {
					if (this.type === "select") {
						this.$refs.newTagSelectRef.focus();
					} else {
						this.$refs.newTagInputRef.$refs.input.focus();
					}
				});
			},

			// 文本框模式下的失焦事件
			inputBlurHandler(e) {
				this.isAdding = false;
				this.inputValue && this.$emit("modify", this.inputValue);
				this.inputValue = "";
			},

			// 选择器模式下的选项更改(被选择)事件
			selectionChangeHandler(value) {
				this.$emit("modify", [...this.items, value]);
				this.selectedItem = null;
				this.selectKey = Math.random().toString();
			},

			// 选择器模式下的失焦事件
			selectBlurHandler(e) {
				this.isAdding = false;
			},

			// tag的叉号点击事件
			handleDelete(value) {
				let items = this.items.slice();
				const index = items.indexOf(value);
				if (index > -1) items.splice(index, 1);
				this.$emit("modify", items);
			}
		}
	};
</script>

<style lang="less" scoped>
	.row-items {
		display: flex;
		align-items: center;
		flex-wrap: wrap;
		padding-left: 10px;
		.el-tag {
			margin: 5px 10px 5px 0;
		}
	}
	.box-bottom {
		padding-top: 10px;
		border-top: 1px solid #ccc;
	}
</style>
